package com.example.spider.task;

import com.example.spider.cluster.msg.MsgSender;
import com.example.spider.config.ThreadPoolConfiguration;
import com.example.spider.config.support.ExceptionHandlerExceptionResolver;
import lombok.extern.slf4j.Slf4j;
import org.shoulder.core.context.AppInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.ExecutorService;

/**
 * 爬虫结果处理器
 *
 * @author lym
 */
@SuppressWarnings("rawtypes")
@Slf4j
@Service
public class SpiderResultHandlerManager {

    @Qualifier(ThreadPoolConfiguration.HANDLER)
    @Autowired
    private ExecutorService executor;

    private final List<SpiderResultHandler> resultHandlers;

    @Autowired(required = false)
    private ExceptionHandlerExceptionResolver exceptionResolver;

    @Autowired(required = false)
    private MsgSender msgSender;

    public SpiderResultHandlerManager(List<SpiderResultHandler> resultHandlers) {
        this.resultHandlers = resultHandlers;
    }

    @SuppressWarnings("unchecked")
    public <T> void handle(Task<T> task, T result) {
        if (result == null || resultHandlers == null) {
            return;
        }
        log.debug("handle spiderTaskResult " + task.getUrl());
        executor.execute(() -> {
            // 责任链
            boolean missHandle = true;
            for (SpiderResultHandler handler : resultHandlers) {
                try {
                    if (handler.canHandle(task, result)) {
                        missHandle = false;
                        //log.info.txt("handle spiderTaskResult " + task.getUrl());
                        handler.handle(task, result);
                        //log.info.txt("finish handle spiderTaskResult " + task.getClass().getSimpleName() + task.getUrl());
                    }
                } catch (Exception ex) {
                    exceptionResolver.resolveException(task, result, handler, ex);
                }
            }
            if (missHandle) {
                // cluster 爬虫各个节点都能爬，如果本实例不支持处理本次结果，结果为文本类型且支持集群，则转发至结果队列，由其他实例处理
                boolean strResult = task.supportCluster() && AppInfo.cluster() && result instanceof CharSequence;
                if (strResult && msgSender != null) {
                    msgSender.addSpiderResult((AbstractSpiderTask<?>) task, String.valueOf(result));
                    log.info("Miss Handler, task={} reDispatcher=true", task.getClass().getSimpleName());
                } else {
                    log.warn("Miss Handler, task={} reDispatcher=false", task.getClass().getSimpleName());
                }
            }
        });
        log.debug("finish handle spiderTaskResult {} url={}", task.getClass().getSimpleName(), task.getUrl());
    }


}
